package com.csun.cmny.provider.service.impl;

import com.csun.cmny.base.constant.GlobalConstant;
import com.csun.cmny.base.dto.LoginAuthDto;
import com.csun.cmny.base.enums.ErrorCodeEnum;
import com.csun.cmny.core.support.BaseService;
import com.csun.cmny.provider.dao.OmcConvertMapper;
import com.csun.cmny.provider.dto.ConvertDto;
import com.csun.cmny.provider.dto.ConvertQueryDto;
import com.csun.cmny.provider.exceptions.OmcBizException;
import com.csun.cmny.provider.model.domain.OmcConvert;
import com.csun.cmny.provider.model.domain.OmcGift;
import com.csun.cmny.provider.model.dto.volunteer.VolunteerQueryDto;
import com.csun.cmny.provider.model.enums.OmcConvertStatEnum;
import com.csun.cmny.provider.model.enums.OmcConvertTypeEnum;
import com.csun.cmny.provider.model.vo.VolunteerVo;
import com.csun.cmny.provider.resolver.CmnyMessageSource;
import com.csun.cmny.provider.service.OmcConvertService;
import com.csun.cmny.provider.service.OmcGiftService;
import com.csun.cmny.provider.service.UacRpcService;
import com.csun.cmny.provider.vo.ConvertVo;
import com.csun.cmny.provider.vo.GiftVo;
import com.csun.cmny.util.PubUtils;
import com.csun.cmny.util.PublicUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Auther: chisj chisj@foxmal.com
 * @Date: 2019-05-23 21:19
 * @Description: the omc convert service impl
 */
@Slf4j
@Service
@Transactional
public class OmcConvertServiceImpl extends BaseService<OmcConvert> implements OmcConvertService {

    @Resource
    private OmcConvertMapper omcConvertMapper;

    @Resource
    private OmcGiftService omcGiftService;

    @Resource
    private UacRpcService uacRpcService;

    @Resource
    private CmnyMessageSource cmnyMessageSource;

    /**
     * 礼品兑换
     *
     * @param convertDto   convert dto
     * @param loginAuthDto login auth dto
     * @return the int.
     */
    @Override
    public Integer addConvert(ConvertDto convertDto, LoginAuthDto loginAuthDto) {

        Integer result = -1;
        OmcConvert omcConvert = new OmcConvert();

        // 校验志愿者是否存在
        VolunteerVo volunteerVo = uacRpcService.getVolunteerByVolunteerId(convertDto.getVolunteerId());
        if (PublicUtil.isEmpty(volunteerVo)) {
            throw new OmcBizException(ErrorCodeEnum.UAC10018002);
        }

        // 校验礼品是否存在
        OmcGift omcGift = omcGiftService.selectByKey(convertDto.getGiftId());
        if (PublicUtil.isEmpty(omcGift)) {
            throw new OmcBizException(ErrorCodeEnum.OMC10031018);
        }

        omcConvert.setGiftPic(omcGift.getGiftPic());
        omcConvert.setGiftName(omcGift.getGiftName());
        omcConvert.setGiftNo(omcGift.getGiftNo());
        omcConvert.setGiftRemark(omcGift.getRemark());
        omcConvert.setPrice(omcGift.getPrice());

        // 校验礼品库存
        if (omcGift.getStock().compareTo(0) <= 0) {
            throw new OmcBizException(ErrorCodeEnum.OMC10031019);
        }

        // 校验志愿者积分是否大于积分
        if (volunteerVo.getIntegral().compareTo(omcGift.getIntegral()) < 0) {
            throw new OmcBizException(ErrorCodeEnum.OMC10031020);
        }

        omcConvert.setIntegral(omcGift.getIntegral());

        // 线上兑换
        if (convertDto.getConvertType().equals(OmcConvertTypeEnum.ONLINE.getKey())) {
            // 校验物流信息
            Preconditions.checkArgument(PublicUtil.isNotEmpty(convertDto.getLgsCompany()),
                    cmnyMessageSource.getMessage("convert.lgs.company.null", null));
            Preconditions.checkArgument(PublicUtil.isNotEmpty(convertDto.getLgsNumber()),
                    cmnyMessageSource.getMessage("convert.lgs.number.null", null));

            // 物流单号唯一校验
            OmcConvert omcConvertQuery = new OmcConvert();
            omcConvertQuery.setLgsNumber(convertDto.getLgsNumber());
            int count = selectCount(omcConvertQuery);
            if (count > 0) {
                throw new OmcBizException(ErrorCodeEnum.OMC10031025);
            }

            omcConvert.setStat(OmcConvertStatEnum.IS_SEND.getKey());
        } else {
            omcConvert.setStat(OmcConvertStatEnum.FINISH.getKey());
        }

        // 扣除志愿者积分
        Integer integral = volunteerVo.getIntegral() - omcGift.getIntegral();
        result = uacRpcService.updateVolunteerIntegralByVolunteerId(convertDto.getVolunteerId(), integral);
        if (result < 1) {
            // 扣除积分失败
            throw new OmcBizException(ErrorCodeEnum.OMC10031021);
        }

        // 减少礼品库存
        result = omcGiftService.convertGift(omcGift);
        if (result < 1) {
            // 扣除库存失败
            throw new OmcBizException(ErrorCodeEnum.OMC10031022);
        }

        BeanUtils.copyProperties(convertDto, omcConvert);
        omcConvert.setUpdateInfo(loginAuthDto);

        return omcConvertMapper.insertSelective(omcConvert);
    }

    /**
     * 礼品兑换记录分页查询
     *
     * @param convertQueryDto convert query dto
     * @return the page info.
     */
    @Override
    public PageInfo queryConvertListWithPage(ConvertQueryDto convertQueryDto) {

        Map<Long, VolunteerVo> volunteerVoMap = Maps.newHashMap();
        List<VolunteerVo> volunteerVoList = Lists.newArrayList();
        List<Long> volunteerIdList = Lists.newArrayList();

        // 判断是否有volunteerId
        if (PublicUtil.isEmpty(convertQueryDto.getVolunteerId())) {
            // 判断是否有姓名，电话，性别
            if (PublicUtil.isNotEmpty(convertQueryDto.getUserName())
                    || PublicUtil.isNotEmpty(convertQueryDto.getMobileNo())
                    || PublicUtil.isNotEmpty(convertQueryDto.getSex())) {
                // 查询志愿者Id集合
                VolunteerQueryDto volunteerQueryDto = new VolunteerQueryDto();
                BeanUtils.copyProperties(convertQueryDto, volunteerQueryDto);
                volunteerQueryDto.setPageSize(GlobalConstant.MAX_PAGE_SIZE);
                volunteerVoList = uacRpcService.queryVolunteerListWithPage(volunteerQueryDto);
                if (PublicUtil.isNotEmpty(volunteerVoList)) {
                    for (VolunteerVo v : volunteerVoList) {
                        volunteerVoMap.put(v.getId(), v);
                        volunteerIdList.add(v.getId());
                    }
                    convertQueryDto.setVolunteerIdList(volunteerIdList);
                } else {
                    return new PageInfo<>(Lists.newArrayList());
                }
            }
        } else {
            // 根据志愿者Id获取志愿者信息
            VolunteerVo volunteerVo = uacRpcService.getVolunteerByVolunteerId(convertQueryDto.getVolunteerId());
            volunteerVoMap.put(volunteerVo.getId(), volunteerVo);
        }

        PageHelper.startPage(convertQueryDto.getPageNum(), convertQueryDto.getPageSize());
        List<ConvertVo> convertVoList = omcConvertMapper.queryConvertListWithPage(convertQueryDto);

        if (PublicUtil.isEmpty(volunteerVoMap)) {
            volunteerIdList = convertVoList
                    .stream().map(c -> c.getVolunteerId()).collect(Collectors.toList());

            volunteerVoList = uacRpcService.queryVolunteerListByVolunteerIds(volunteerIdList);
            if (PublicUtil.isNotEmpty(volunteerVoList)) {
                volunteerVoMap = volunteerVoList
                        .stream().collect(Collectors.toMap(VolunteerVo::getId, volunteerVo -> volunteerVo));
            }
        }

        for (ConvertVo c : convertVoList) {
            VolunteerVo v = volunteerVoMap.get(c.getVolunteerId());
            if (PublicUtil.isNotEmpty(v)) {
                // BeanUtils.copyProperties(v, c);
                c.setUserName(v.getUserName());
                c.setMobileNo(v.getMobileNo());
                c.setSex(v.getSex());
                c.setLoginName(v.getLoginName());
                c.setIdCard(v.getIdCard());
            }
        }

        return new PageInfo<>(convertVoList);
    }
}
